Form validation is an important part of any app.
In this article, we’ll look at how to use Vee-Validate 4 in our Vue 3 app for form validation.
Dynamic Form with Initial Values
We can set initial values for dynamic forms as we do with static forms.
To do this, we pass in an object with the values into the initial-values
prop:
<template>
<Form
v-slot="{ errors }"
:validation-schema="schema.validation"
:initial-values="schema.values"
>
<div v-for="field in schema.fields" :key="field.name">
<label :for="field.name">{{ field.label }}</label>
<Field :as="field.as" :id="field.name" :name="field.name" />
<span>{{ errors[field.name] }}</span>
</div>
<button>Submit</button>
</Form>
</template>
<script>
import { Form, Field } from "vee-validate";
import * as yup from "yup";
export default {
name: "DynamicForm",
components: {
Form,
Field,
},
data() {
return {
schema: {
fields: [
{
label: "Name",
name: "name",
as: "input",
},
{
label: "Email",
name: "email",
as: "input",
},
{
label: "Password",
name: "password",
as: "input",
},
],
validation: yup.object().shape({
email: yup.string().email().required(),
name: yup.string().required(),
password: yup.string().min(8).required(),
}),
values: {
name: "james",
email: "abc@abc.com",
password: "password",
},
},
};
},
};
</script>
We add the values
property with the values into the schema
reactive property.
Then we pass that into the validation-schema
prop.
The property names of schema.values
should match the values of the name
prop of the field we want to fill in.
Now we should see the initial form values populated.
Reducing App Bundle Size
To reduce the bundle size of our app, we can selectively import the parts of the yup
module we require.
For example, instead of writing:
<template>
<Form
v-slot="{ errors }"
:validation-schema="schema.validation"
:initial-values="schema.values"
>
<div v-for="field in schema.fields" :key="field.name">
<label :for="field.name">{{ field.label }}</label>
<Field :as="field.as" :id="field.name" :name="field.name" />
<span>{{ errors[field.name] }}</span>
</div>
<button>Submit</button>
</Form>
</template>
<script>
import { Form, Field } from "vee-validate";
import * as yup from "yup";
export default {
name: "DynamicForm",
components: {
Form,
Field,
},
data() {
return {
schema: {
fields: [
{
label: "Name",
name: "name",
as: "input",
},
{
label: "Email",
name: "email",
as: "input",
},
{
label: "Password",
name: "password",
as: "input",
},
],
validation: yup.object().shape({
email: yup.string().email().required(),
name: yup.string().required(),
password: yup.string().min(8).required(),
}),
},
};
},
};
</script>
We can write:
<template>
<Form
v-slot="{ errors }"
:validation-schema="schema.validation"
:initial-values="schema.values"
>
<div v-for="field in schema.fields" :key="field.name">
<label :for="field.name">{{ field.label }}</label>
<Field :as="field.as" :id="field.name" :name="field.name" />
<span>{{ errors[field.name] }}</span>
</div>
<button>Submit</button>
</Form>
</template>
<script>
import { Form, Field } from "vee-validate";
import { object, string } from "yup";
export default {
name: "DynamicForm",
components: {
Form,
Field,
},
data() {
return {
schema: {
fields: [
{
label: "Name",
name: "name",
as: "input",
},
{
label: "Email",
name: "email",
as: "input",
},
{
label: "Password",
name: "password",
as: "input",
},
],
validation: object().shape({
email: string().email().required(),
name: string().required(),
password: string().min(8).required(),
}),
},
};
},
};
</script>
We just import the object
and string
methods form the yup
module, then we call them to create our schema.
Conclusion
We can add dynamic forms with initial values easily into our Vue 3 dynamic forms with Vee-Validate 4.
Also, we can reduce bundle size by selectively importing items from the yup
module.